﻿using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TaiwuModFramework.Common.Abstract;
using TaiwuModFramework.Common.Attribute;
using TaiwuModFramework.Common.Info;

namespace TaiwuModFramework.Common.Base {
    public class BaseTaiwuComp : AService {

        protected Harmony harmony { get; private set; } = null;
        // 配置项列表
        private protected List<ConfigItemInfo> configItemInfoList = null;

        public bool CompEnable {
            get { return harmony != null; }
            protected set {
                if(value == true) {
                    Patch();
                } else {
                    Dispatch();
                }
            }
        }

        public void Enable() {
            CompEnable = true;
        }
        private void Patch() {
            if(harmony == null) {
                Log.Info("激活组件补丁\t{0}", GetType().FullName);
                harmony = Harmony.CreateAndPatchAll(this.GetType());
            }
        }

        private void Dispatch() {
            if(harmony != null) {
                Log.Info("禁用组件补丁\t{0}", GetType().FullName);
                harmony.UnpatchSelf();
                harmony = null;
            }
        }

        public string ModIdStr { get; private set; }
        public string CompName { get; protected set; }
        public string CompDescription { get; protected set; }

        /// <summary>
        /// 获取所有配置的字段和属性列表
        /// <para>[ConfigItem(name)]</para>
        /// <para>若有name则BaseConfigItem.ConfigKey = name</para>
        /// <para>否则BaseConfigItem.ConfigKey = Field.Name</para>
        /// </summary>
        /// <returns>配置项的字段或属性列表</returns>
        public List<ConfigItemInfo> GetConfigItemInfoList() {
            if(configItemInfoList != null) {
                return configItemInfoList;

            }
            configItemInfoList = new List<ConfigItemInfo>();
            Type type = GetType();
            // 添加一个用于控制组件通用开关的属性
            var prop = type.GetProperty("CompEnable", BindingFlags.Instance | BindingFlags.NonPublic);
            if(prop != null) {
                var key = string.Format("{0}.{1}", type.FullName, "Enable").Replace('.', '_');
                configItemInfoList.Add(new ConfigItemInfo(this, prop, key));
            }

            AttrConfigItem tmpAttr; // 暂存配置特性
            ConfigItemInfo tmpCII;  // 暂存配置项信息

            // 读取有特性描述的属性
            foreach(var fieldOrProp in type.GetProperties(AttrConfigItem.Flag)) {
                tmpAttr = fieldOrProp.GetCustomAttribute<AttrConfigItem>();
                if(tmpAttr != null) { // 只有不为null，才表示是配置项
                    var configItemKey = tmpAttr.ConfigItemKey;
                    tmpCII = new ConfigItemInfo(this, fieldOrProp,
                        String.IsNullOrEmpty(configItemKey) ? fieldOrProp.Name : configItemKey);
                    configItemInfoList.Add(tmpCII);
                    tmpCII = null;
                }
            }
            // 读取有特性描述的字段
            foreach(var fieldOrProp in type.GetFields(AttrConfigItem.Flag)) {
                tmpAttr = fieldOrProp.GetCustomAttribute<AttrConfigItem>();
                if(tmpAttr != null) { // 只有不为null，才表示是配置项
                    var configItemKey = tmpAttr.ConfigItemKey;
                    tmpCII = new ConfigItemInfo(this, fieldOrProp,
                        String.IsNullOrEmpty(configItemKey) ? fieldOrProp.Name : configItemKey);
                    configItemInfoList.Add(tmpCII);
                    tmpCII = null;
                }
            }


            return configItemInfoList;
        }

        public virtual void OnModSettingUpdate() {
        }

        public virtual void OnLoadedArchiveData() {
        }

        public virtual void OnEnterNewWorld() {
        }

        public void CallOnModSettingUpdate() {
            if(CompEnable) {
                OnModSettingUpdate();
            }
        }

        public void CallOnLoadedArchiveData() {
            if(CompEnable) {
                OnLoadedArchiveData();
            }
        }

        public void CallOnEnterNewWorld() {
            if(CompEnable) {
                OnEnterNewWorld();
            }
        }



        public override string ToString() {
            GetConfigItemInfoList();
            StringBuilder sb = new StringBuilder('{');
            sb.Append(string.Format("{0}\tEnable:{1}", GetType().Name, CompEnable));
            sb.Append("\t配置项：{\t");
            foreach(var info in configItemInfoList) {
                sb.Append(info).Append(' ');
            }
            sb.Append("}\t}");
            return sb.ToString();
        }

        public static string PatchListToStr(List<BaseTaiwuComp> list) {
            var sb = new StringBuilder();
            sb.Append("{");
            if(list != null && list.Count > 0) {
                sb.Append("\n");
                for(int i = 0; i < list.Count; i++) {
                    sb.Append("\t").Append(list[i]);
                    if(i < list.Count - 1) sb.Append(",\n");
                }
                sb.Append("\n");
            }
            sb.Append("}");
            return sb.ToString();

        }
    }
}
